home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
201-225
/
225
/
mymenu
/
menu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
7KB
|
250 lines
/* Copyright ) Darin Johnson, 1989 */
#include <exec/memory.h>
#include <graphics/text.h>
#include <graphics/gfxbase.h>
#include <intuition/intuition.h>
#include <clib/macros.h>
#include <functions.h>
#include "MyMenu.h"
BYTE *copystr();
unsigned long mnum, inum, snum, menu_num;
struct ext_MenuItem *tail_list;
UWORD font_width, font_height;
UBYTE menu_pen; /* pen number for newly created items */
extern struct GfxBase *GfxBase;
struct Menu *mptr;
struct MenuItem *iptr, *sptr;
/* clean things up and initialize */
start_menu() {
MM->my_menu = NULL;
menu_pen = 0; /* default */
MM->item_list = tail_list = NULL;
font_width = GfxBase->DefaultFont->tf_XSize;
font_height = GfxBase->DefaultFont->tf_YSize;
}
/* clean up widths and other info now that menu is all built */
end_menu() {
UWORD maxw, smaxw, txtw, top, stop, left;
ULONG ilock;
if (MM->prev_menu) {
ilock = LockIBase(0L);
left = MM->prev_menu->LeftEdge + MM->prev_menu->Width + SEPARATE;
UnlockIBase(ilock);
}
for (mptr = MM->my_menu; mptr; mptr=mptr->NextMenu) {
mptr->LeftEdge = left;
maxw = mptr->Width = (strlen(mptr->MenuName)+1) * font_width;
maxw += SEPARATE;
left += maxw;
top = 0;
/* determine max width */
for (iptr = mptr->FirstItem; iptr; iptr=iptr->NextItem) {
iptr->TopEdge = top;
top += iptr->Height;
txtw = IntuiTextLength(iptr->ItemFill);
if (iptr->Flags & COMMSEQ)
txtw += COMMWIDTH+font_width+4;
if (txtw > maxw)
maxw = txtw;
}
for (iptr = mptr->FirstItem; iptr; iptr=iptr->NextItem) {
iptr->Width = maxw;
stop = smaxw = 0;
for (sptr=iptr->SubItem; sptr; sptr=sptr->NextItem) {
sptr->LeftEdge = maxw;
sptr->TopEdge = stop;
stop += sptr->Height;
txtw = IntuiTextLength(sptr->ItemFill);
if (sptr->Flags & COMMSEQ)
txtw += COMMWIDTH+font_width+4;
if (txtw > smaxw)
smaxw = txtw;
}
for (sptr=iptr->SubItem; sptr; sptr=sptr->NextItem)
sptr->Width = smaxw;
}
}
}
/* allocate and initialize a new menu */
struct Menu *new_menu(menustr)
char *menustr;
{
struct Menu *menu;
menu = (struct Menu *)
AllocMem(sizeof(struct Menu), MEMF_PUBLIC|MEMF_CLEAR);
menu->MenuName = copystr(menustr);
menu->Flags = MENUENABLED;
menu->NextMenu = NULL;
menu->FirstItem = NULL;
menu->TopEdge = menu->Height = 0;
return menu;
}
/* Find a menu. If not found, create a new one */
struct Menu *get_menu(menustr)
char *menustr;
{
struct Menu *menu, *prev;
mnum = menu_num + 1;
if (MM->my_menu == NULL) /* our menu strip */
menu = MM->my_menu = new_menu(menustr);
else {
for (menu=MM->my_menu; menu; menu=menu->NextMenu) {
if (!strcmp(menustr, (char *)menu->MenuName))
break; /* already here */
prev = menu;
mnum++;
}
if (menu == NULL)
menu = prev->NextMenu = new_menu(menustr);
}
return menu;
}
/* create and initialize a new menu item */
struct MenuItem *new_item(itemstr)
char *itemstr;
{
struct MenuItem *item;
struct IntuiText *it;
/* notice that we allocate extra space */
item = (struct MenuItem *)
AllocMem(sizeof(struct ext_MenuItem), MEMF_PUBLIC|MEMF_CLEAR);
it = (struct IntuiText *)
AllocMem(sizeof(struct IntuiText), MEMF_PUBLIC|MEMF_CLEAR);
item->NextItem = item->SubItem = NULL;
item->SelectFill = NULL;
item->NextSelect = 0;
item->Height = font_height + 1;
item->LeftEdge = item->TopEdge = item->MutualExclude = 0;
item->Flags = ITEMTEXT+HIGHCOMP+ITEMENABLED;
it->FrontPen = menu_pen;
it->BackPen = AUTOBACKPEN;
it->LeftEdge = it->TopEdge = 1;
it->ITextFont = NULL;
it->NextText = NULL;
it->DrawMode = JAM2;
it->IText = (UBYTE*)copystr(itemstr);
item->ItemFill = (APTR)it;
return item;
}
/* find a menu item, if not found, create a new one */
struct MenuItem *get_item(menustr, itemstr)
char *menustr, *itemstr;
{
struct Menu *menu;
struct MenuItem *item, *prev;
menu = get_menu(menustr);
inum = 0;
if (menu->FirstItem == NULL)
item = menu->FirstItem = new_item(itemstr);
else {
for (item=menu->FirstItem; item; item=item->NextItem) {
if (!strcmp(itemstr, ((struct IntuiText *)item->ItemFill)->IText))
break; /* already here */
prev = item;
inum++;
}
if (item == NULL)
item = prev->NextItem = new_item(itemstr);
}
return item;
}
#define EITEM ((struct ext_MenuItem *)item)
/* create a new menu item (or sub item) */
struct ext_MenuItem *add_menu(menustr, itemstr, substr, comm)
char *menustr, *itemstr, *substr, comm;
{
struct MenuItem *item, *sub, *prev;
if (!itemstr)
return NULL; /* oops */
item = get_item(menustr, itemstr); /* get (or create) the item */
if (substr && *substr) {
snum = 0;
if (item->SubItem == NULL)
sub = item->SubItem = new_item(substr); /* get the sub-item */
else {
for (sub=item->SubItem; sub; sub=sub->NextItem) {
if (!strcmp(substr, (char *)sub->ItemFill))
break; /* duplicate */
prev = sub;
snum++;
}
if (sub == NULL)
sub = prev->NextItem = new_item(substr);
}
item = sub;
} else
snum = NOSUB;
if (comm) {
item->Command = comm;
item->Flags |= COMMSEQ;
}
/* fill in our private fields */
EITEM->id = SHIFTMENU(mnum)|SHIFTITEM(inum)|SHIFTSUB(snum);
EITEM->cmd = EITEM->args = NULL;
EITEM->type = NULL;
/* stick onto item_list */
EITEM->next_item = NULL;
if (MM->item_list==NULL)
MM->item_list = EITEM;
else
tail_list->next_item = EITEM;
tail_list = EITEM;
return EITEM;
}
/* free up memory used by a menu item */
free_item(item)
struct ext_MenuItem *item;
{
struct IntuiText *it;
it = (struct IntuiText *)item->MenuItem.ItemFill;
FreeMem(it->IText, strlen(it->IText)+1);
FreeMem(it, sizeof(struct IntuiText));
if (item->cmd)
FreeMem(item->cmd, strlen(item->cmd)+1);
if (item->args)
FreeMem(item->args, strlen(item->args)+1);
FreeMem(item, sizeof(struct ext_MenuItem));
}
/* free up all space taken up by our menus */
free_menus() {
struct Menu *mtmp;
struct MenuItem *itmp;
mptr = MM->my_menu;
MM->my_menu = NULL;
while (mptr) {
iptr = mptr->FirstItem;
while (iptr) {
sptr = iptr->SubItem;
while (sptr) {
itmp = sptr;
sptr = sptr->NextItem;
free_item(itmp);
}
itmp = iptr;
iptr = iptr->NextItem;
free_item(itmp);
}
mtmp = mptr;
mptr = mptr->NextMenu;
FreeMem(mtmp->MenuName, strlen(mtmp->MenuName)+1);
FreeMem(mtmp, sizeof(struct Menu));
}
}